package com.baiye.template.config;

import com.baiye.template.filter.JwtLoginFilter;
import com.baiye.template.filter.JwtVerifyFilter;
import com.baiye.template.service.UserService;
import com.baiye.template.utils.PasswordEncoderUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;

/**
 * @author GUOZHIPENG
 * @version 1.0
 * @date 2021/8/26 17:18
 */
@Configuration
//暂时关闭

//web安全
@EnableWebSecurity
//权限
//@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private final UserService userService;
    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;
    @Autowired
    private CustomizeAuthenticationFailureHandler authenticationFailureHandler;
    @Autowired
    private CustomizeAuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    private CustomizeLogoutSuccessHandler logoutSuccessHandler;
    //访问决策管理器
    @Autowired
    CustomizeAccessDecisionManager accessDecisionManager;

    //实现权限拦截
    @Autowired
    CustomizeFilterInvocationSecurityMetadataSource securityMetadataSource;

    public WebSecurityConfig(UserService userService) {
        this.userService = userService;
    }


    @Bean
    public PasswordEncoderUtils passwordEncoder() {
        return new PasswordEncoderUtils();
    }

    /**
     * 认证用户的来源
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //通过数据库验证登录
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    /**
     * 配置SpringSecurity相关信息
     *
     * @param http
     * @throws Exception
     */
    //暂时关闭
    @Override
    public void configure(HttpSecurity http) throws Exception {

        http.cors().and()
                .csrf().disable()//关闭csrf
                .addFilter(new JwtVerifyFilter(super.authenticationManager()))
                .authorizeRequests().
                 withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O o) {
                        o.setAccessDecisionManager(accessDecisionManager);//决策管理器
                        o.setSecurityMetadataSource(securityMetadataSource);//安全元数据源
                        return o;
                    }
                }).and()


                //登入
                .formLogin().
                permitAll().//允许所有用户
                successHandler(authenticationSuccessHandler).//登录成功处理逻辑
                failureHandler(authenticationFailureHandler).//登录失败处理逻辑


                and().

                //登出
                logout().
                permitAll().//允许所有用户
                logoutSuccessHandler(logoutSuccessHandler)//登出成功处理逻辑


                .and()

//                .formLogin().loginProcessingUrl("/login").and()

                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)    //禁用session
                //异常处理(权限拒绝、登录失效等)
                .and().exceptionHandling().
                authenticationEntryPoint(authenticationEntryPoint);//匿名用户访问无权限资源时的异常处理




    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/static/**");//放行静态资源
    }
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http.csrf().disable().authorizeRequests().anyRequest().permitAll().and().logout().permitAll();
//    }


}
